Sparsereshape ================= 对稀疏张量进行形状重塑(Reshape)。该算子将稀疏张量的索引从输入形状转换到输出形状,不改变稀疏值本身,只更新索引。该算子不区分数据类型,只处理索引信息。 对于每个稀疏元素: - 计算其在输入形状中的线性索引: :math:`\text{ori\_index} = \sum_{j=0}^{\text{input\_rank}-1} \text{in\_indices}[j] \times \text{in\_stride}[j]` - 将线性索引转换为输出形状的多维索引: :math:`\text{out\_indices}[j] = \text{ori\_index} / \text{out\_stride}[j]`,然后 :math:`\text{ori\_index} = \text{ori\_index} \% \text{out\_stride}[j]` 输入: - **in_indices_ptr** - 输入稀疏张量的索引数组,大小为 `N * input\_rank`,每 `input\_rank` 个元素表示一个非零元素的索引。 - **in_inshape_ptr** - 输入稀疏张量的形状数组,大小为 `input\_rank`,例如 `[2, 3]` 表示 2×3 的矩阵。 - **in_outshape_ptr** - 目标输出形状数组,大小为 `output_rank`,例如 `[3, 2]` 表示要将形状转换为 3×2。 - **out_outshape_ptr** - 输出形状数组,应该与 `in_outshape_ptr` 一致,大小为 `output_rank`。 - **input_rank** - 输入稀疏张量的维度数。 - **output_rank** - 输出稀疏张量的维度数。 - **N** - 稀疏张量中非零元素的数量。 - **in_stride** - 输入形状的步长数组(临时空间),大小为 `input_rank`,用于中间计算。 - **out_stride** - 输出形状的步长数组(临时空间),大小为 `output_rank`,用于中间计算。 - **core_mask** - 核掩码(仅共享存储版本需要)。 输出: - **out_indices_ptr** - 转换后的索引数组,大小为 `N * output_rank`,每 `output_rank` 个元素表示一个非零元素在输出形状中的索引。 支持平台: ``FT78NE`` ``MT7004`` .. note:: - FT78NE 支持fp32 - MT7004 支持fp32 **共享存储版本:** .. c:function:: void sparsereshape_s(int* in_indices_ptr, int* in_inshape_ptr, int* in_outshape_ptr, int* out_indices_ptr, int* out_outshape_ptr, int input_rank, int output_rank, int N, int* in_stride, int* out_stride, int core_mask) **C调用示例:** .. code-block:: c :linenos: :emphasize-lines: 31-33 //FT78NE示例 #include #include int main(int argc, char* argv[]) { // 假设在DDR空间 int N = 3; // 有3个非零元素 int input_rank = 2; // 输入是2维 int output_rank = 2; // 输出也是2维 // 输入形状 [2, 3],输出形状 [3, 2] int in_inshape[] = {2, 3}; int in_outshape[] = {3, 2}; int out_outshape[] = {3, 2}; // 应该和 in_outshape 一致 // 输入索引:[[0,0], [0,1], [1,2]] int *in_indices_ptr = (int *)0xA0000000; in_indices_ptr[0] = 0; in_indices_ptr[1] = 0; // 第一个元素在位置(0,0) in_indices_ptr[2] = 0; in_indices_ptr[3] = 1; // 第二个元素在位置(0,1) in_indices_ptr[4] = 1; in_indices_ptr[5] = 2; // 第三个元素在位置(1,2) // 输出索引(待填充) int *out_indices_ptr = (int *)0xB0000000; // 临时空间:步长数组 int *in_stride = (int *)0xC0000000; // 大小为 input_rank int *out_stride = (int *)0xC0100000; // 大小为 output_rank int core_mask = 0xff; sparsereshape_s(in_indices_ptr, in_inshape, in_outshape, out_indices_ptr, out_outshape, input_rank, output_rank, N, in_stride, out_stride, core_mask); return 0; } **私有存储版本:** .. c:function:: void sparsereshape_p(int* in_indices_ptr, int* in_inshape_ptr, int* in_outshape_ptr, int* out_indices_ptr, int* out_outshape_ptr, int input_rank, int output_rank, int N, int* in_stride, int* out_stride) **C调用示例:** .. code-block:: c :linenos: :emphasize-lines: 24-26 //FT78NE示例 #include #include int main(int argc, char* argv[]) { // 假设在L2空间 int N = 3; int input_rank = 2; int output_rank = 2; int in_inshape[] = {2, 3}; int in_outshape[] = {3, 2}; int out_outshape[] = {3, 2}; int *in_indices_ptr = (int *)0x10000000; in_indices_ptr[0] = 0; in_indices_ptr[1] = 0; in_indices_ptr[2] = 0; in_indices_ptr[3] = 1; in_indices_ptr[4] = 1; in_indices_ptr[5] = 2; int *out_indices_ptr = (int *)0x10001000; int *in_stride = (int *)0x10002000; int *out_stride = (int *)0x10003000; sparsereshape_p(in_indices_ptr, in_inshape, in_outshape, out_indices_ptr, out_outshape, input_rank, output_rank, N, in_stride, out_stride); return 0; }